package maps

import (
	"maps"

	"gitee.com/makitdone/gx"
)

func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool {
	return maps.Equal(m1, m2)
}

func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool {
	return maps.EqualFunc(m1, m2, eq)
}

func Clone[M ~map[K]V, K comparable, V any](m M) M {
	return maps.Clone(m)
}

func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src ...M2) {
	for _, s := range src {
		maps.Copy(dst, s)
	}
}

func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) {
	maps.DeleteFunc(m, del)
}

// 合并并返回新的map
func Merge[M ~map[K]V, K comparable, V any](src ...M) M {
	result := make(M)
	for _, m := range src {
		Copy(result, m)
	}
	return result
}

func MergeFunc[M ~map[K]V, K comparable, V any](f func(K, V) bool, src ...M) M {
	result := make(M)
	for _, m := range src {
		for k, v := range m {
			if f(k, v) {
				result[k] = v
			}
		}
	}
	return result
}

// 深层合并map
func DeepMerge(src ...map[string]any) map[string]any {
	result := map[string]any{}
	for _, m := range src {
		for k, v := range m {
			val := result[k]
			if gx.IsMap(val) && gx.IsMap(v) {
				result[k] = DeepMerge(val.(map[string]any), v.(map[string]any))
			} else if gx.IsSlice(val) && gx.IsSlice(v) {
				result[k] = append(val.([]any), v.([]any)...)
			} else {
				result[k] = v
			}
		}
	}
	return result
}

func Keys[M ~map[K]V, K comparable, V any](m M) []K {
	r := make([]K, 0, len(m))
	for k := range m {
		r = append(r, k)
	}
	return r
}

func Values[M ~map[K]V, K comparable, V any](m M) []V {
	r := make([]V, 0, len(m))
	for _, v := range m {
		r = append(r, v)
	}
	return r
}
